/**
 * The Footbar global namespace
 * @class Footbar.Util
 * @static
 */
if (typeof Footbar == "undefined") {
    Footbar = {};
}

//Ref:http://www.kevlindev.com/tutorials/javascript/inheritance/index.htm#Anchor-On-7601
Footbar.Util={
/**
 * A function used to extend one class with another
 *
 * @param {Object} subClass
 * 		The inheriting class, or subclass
 * @param {Object} baseClass
 * 		The class from which to inherit
 */
    extend: function(subClass, baseClass) {
        function inheritance() {}
        inheritance.prototype = baseClass.prototype;

        subClass.prototype = new inheritance();
        subClass.prototype.constructor = subClass;
        subClass.baseConstructor = baseClass;
        subClass.superClass = baseClass.prototype;
    },

    extendv2:function(subc,superc,overrides){
        var F=function(){};
        F.prototype=superc.prototype;
        subc.prototype=new F();
        subc.prototype.constructor=subc;
        subc.superclass=superc.prototype;
        if(superc.prototype.constructor==Object.prototype.constructor)
        {
            superc.prototype.constructor=superc;
        }
        if(overrides){
            for(var i in overrides){
                subc.prototype[i]=overrides[i];
            }
        }
    },

    findPluginPath:function(isShortPath){
        var path="";
        try {
            netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
        } catch (e) {
            alert("Permission to save file was denied.");
        }
        // get the path to the user's home (profile) directory
        const DIR_SERVICE = new Components.Constructor("@mozilla.org/file/directory_service;1","nsIProperties");
        try {
            path=(new DIR_SERVICE()).get("ProfD", Components.interfaces.nsIFile).path;
        } catch (e) {
            alert("error"+e);
        }
        // determine the file-separator
        var separator="\\";
        if (path.search(/\\/) != -1) {
            separator = "\\";
        } else {
            separator= "/";
        }

        if(isShortPath){
            return path+separator+"extensions"+separator+"footbar@trucoder.com"+separator;
        }

        path=path+separator+"extensions"+separator+"footbar@trucoder.com"+separator+"data"+separator;
        return path;
    },
    isCdataNodeOpen:false,
    serializeNode:function(root, depth){
        var TEXT_NODE=3;
        var CDATA_NODE=4;
        var sXML="";
        var node=root.childNodes;
        for(var i=0;i<node.length;i++){
            var padding="";
            //Indentation
            for(var m=0; m<depth; ++m){
                padding+="  ";
            }
            if(node[i].nodeType==TEXT_NODE){
                if(node[i].textContent!=null && node[i].textContent!="")
                //http://www.codestore.net/store.nsf/unid/BLOG-20060313/
                    var line=node[i].textContent;//gets rid off new lines at the end of the inputsteam
                sXML+=line.replace(/(?:(?:^|\n)\s+|\s+(?:$|\n))/g,"");
                continue;
            }else if(node[i].nodeType==CDATA_NODE){
                sXML+="<![CDATA[";
                sXML+=node[i].textContent;
                sXML+="]]>";
                continue;
            }
            sXML+="\n"+padding+"<"+node[i].nodeName;
            if(node[i].nodeValue!=null){
                sXML+=node[i].textContent;
            }
            //Enumerate Node Attributes
            if(node[i].hasAttributes()){
                var sAttributes="";
                var attributes = node[i].attributes;
                for(var k=0;k<attributes.length;k++){
                    var att=attributes.item(k);
                    sAttributes+=" "+att.nodeName+" = \""+att.nodeValue+"\"";
                }
                sXML+=sAttributes;
            }
            var marker="";
            if(node[i].hasChildNodes()){
                sXML+=">";
            }else{
                sXML+="/>";
                marker=true;
            }
            if(node[i].hasChildNodes()){
                sXML+=this.serializeNode(node[i], ++depth);
            }
            if(!marker){
                sXML+="\n"+padding+"</"+node[i].nodeName+">";
            }
            --depth;
        }
        return sXML;
    },
/**
 * Check if the file exist on the file system
 * @param {Object} path
 */
    fileExist:function(path){
        try {
            netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
        } catch (e) {
            alert("Permission to FileSystem was denied.");
            return false;
        }
        var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
        file.initWithPath( path );
        return file.exists();
    },
/**
 * Write file to the filesystem
 * @param {Object} path
 * @param {Object} output
 */
    writeFileData:function(path, output){
        try {
            netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
        } catch (e) {
            alert("Permission to write file was denied.");
            return;
        }
        var savefile = path;
        var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
        file.initWithPath( savefile );
        if ( file.exists() == false ) {
            dump( "Creating file... " );
            file.create( Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 420 );
        }
        var outputStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance( Components.interfaces.nsIFileOutputStream );

        outputStream.init( file, 0x04 | 0x08 | 0x20, 420, 0 );

        var uc = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
        uc.charset = "UTF-8";
        output = uc.ConvertFromUnicode( output );

        var result = outputStream.write( output, output.length );
        outputStream.close();
    },

/**
 * Convert charaacters from unicode
 * @param {Object} aString
 */
    convertFromUnicode:function(aString){
        if(aString==null || aString=="")return "";
        var uc = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
        uc.charset = "UTF-8";
        try{
            return uc.ConvertFromUnicode( aString );
        }catch(e){
            return "";
        }
    },

/**
 * Read file from the filesystem
 * @ref http://www.captain.at/programming/xul/
 * @param {Object} filename
 */
    readFile:function(filename){
        try {
            netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
        } catch (e) {
            alert("Permission to read file was denied.");
            return "";
        }
        var file = Components.classes["@mozilla.org/file/local;1"]
                .createInstance(Components.interfaces.nsILocalFile);
        file.initWithPath( filename );
        if ( file.exists() == false ) {
            alert("File does not exist");
        }
        var is = Components.classes["@mozilla.org/network/file-input-stream;1"]
                .createInstance( Components.interfaces.nsIFileInputStream );
        is.init( file,0x01, 00004, null);
        var sis = Components.classes["@mozilla.org/scriptableinputstream;1"]
                .createInstance( Components.interfaces.nsIScriptableInputStream );
        sis.init( is );
        var output = sis.read( sis.available() );

        return output;
    },

/**
 * Generate Unique ID
 */
    uid:function(){
        return Math.floor(Math.random()*(new Date().getTime()));
    },

/**
 * Get Current Browser Window
 */
    getBrowser:function(){
        //Ref: http://developer.mozilla.org/en/docs/Code_snippets:Tabbed_browser#Getting_access_to_the_Browser
        var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                .getInterface(Components.interfaces.nsIWebNavigation)
                .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
                .rootTreeItem
                .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                .getInterface(Components.interfaces.nsIDOMWindow);


        return mainWindow.getBrowser();
    },
/**
 * Check if the passed tabURI is open in current browser
 * @param {Object} tabURI Address of URI to check
 */
    isTabURIOpen:function(tabURI){
        var tabURI=this.removeQueryString(tabURI);
        var gBrowser=this.getBrowser();
        var num = gBrowser.browsers.length;
        for (var i = 0; i < num; i++) {
            var b = gBrowser.getBrowserAtIndex(i);
            try {
                var specURI=this.removeQueryString(b.currentURI.spec);
                if(specURI==tabURI){
                    return true;
                }
            } catch(e) {
                alert(e);
            }
        }
        return false;
    },

/**
 * Gain focus on give tabURI
 * @param {Object} tabURI  URI To Focus on
 * @param {Object} gBrowser  Optional Browser window
 */
    focusTab:function(tabURI, gBrowser){
        var tabURI=this.removeQueryString(tabURI);
        var gBrowser=gBrowser||this.getBrowser();
        var num = gBrowser.browsers.length;
        for (var i = 0; i < num; i++) {
            var b = gBrowser.getBrowserAtIndex(i);
            try {
                var specURI=this.removeQueryString(b.currentURI.spec);
                if(specURI==tabURI){
                    gBrowser.selectedTab = b;
                    b.focus();
                    gBrowser.mTabContainer.selectedIndex=i;
                    gBrowser.focus();
                    break;
                }
            } catch(e) {
                alert(e);
            }
        }
    },
/**
 * The Tab have to be Focused in order to get the DOM
 * @param {Object} tabURI
 */
    getTabDOM:function(tabURI){
        this.focusTab(this.removeQueryString(tabURI));

        var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
                .getService(Components.interfaces.nsIWindowMediator);
        var browserWindow = wm.getMostRecentWindow("navigator:browser");

        var tabDOM={
            document:browserWindow.content.document,
            window:browserWindow.content.window.wrappedJSObject
        };
        return tabDOM;
    },
/**
 * Remove trailing query string
 * @param {Object} tabURI
 */
    removeQueryString:function(tabURI){
        return tabURI.split("?")[0];
    },
/**
 * Show Notification message in the slidein/slideout popup window.
 */
    notifyMessage:function(aMessage){
        if(aMessage=="")return;        
        window.openDialog("chrome://footbar/content/notify.xul", "", "chrome,dialog=yes,titlebar=no,popup=yes", aMessage);
    }


}

//http://phrogz.net/JS/Classes/OOPinJS2.html
Function.prototype.inheritsFrom = function( parentClassOrObject ){
    if ( parentClassOrObject.constructor == Function )
    {
        //Normal Inheritance
        this.prototype = new parentClassOrObject;
        this.prototype.constructor = this;
        this.prototype.parent = parentClassOrObject.prototype;
    }
    else
    {
        //Pure Virtual Inheritance
        this.prototype = parentClassOrObject;
        this.prototype.constructor = this;
        this.prototype.parent = parentClassOrObject;
    }
    return this;
}

String.prototype.trim = function() {
    a = this.replace(/^\s+/, '');
    return a.replace(/\s+$/, '');
};
